package com.wuliqing.android.zte.myapplication;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.provider.MediaStore;
import android.support.design.widget.CollapsingToolbarLayout;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.ListAdapter;
import android.widget.ListPopupWindow;
import android.widget.TextView;

import com.wuliqing.android.zte.data.ContactDetailData;
import com.wuliqing.android.zte.fragment.InputDialogFragment;
import com.wuliqing.android.zte.presenter.LoadContactDetailPresenter;
import com.wuliqing.android.zte.service.ContactSaveService;
import com.wuliqing.android.zte.utils.CallUtil;
import com.wuliqing.android.zte.utils.ContactPhotoUtils;

import java.io.FileNotFoundException;
import java.util.ArrayList;

public class DetailActivity extends AppCompatActivity implements LoadContactDetailPresenter.LoadContactDataListener,
        View.OnClickListener, View.OnLongClickListener, InputDialogFragment.OnFragmentInteractionListener, ContactSaveService.Listener {
    private static final int REQUEST_CODE_CAMERA_WITH_DATA = 1001;
    private static final int REQUEST_CODE_PHOTO_PICKED_WITH_DATA = 1002;
    private static final int REQUEST_CROP_PHOTO = 1003;
    // Height and width (in pixels) to request for the photo - queried from the provider.
    private static int mPhotoDim;
    // Default photo dimension to use if unable to query the provider.
    private static final int mDefaultPhotoDim = 720;
    private int mPhotoPickSize;
    private Uri mCroppedPhotoUri;
    private Uri mTempPhotoUri;
    private Uri mCurrentPhotoUri;
    private LoadContactDetailPresenter mLoadContactDetailPresenter;
    private ContactDetailData mContactData;
    private CollapsingToolbarLayout collapsingToolbar;
    private ImageView contact_photo_view;
    private TextView name_textView;
    private TextView number_textView;
    private TextView email_textView;
    private TextView address_textView;
    private TextView organization_textView;
    private TextView note_textView;
    private ProgressDialog mProgressDialog;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_detail);

        initView();
        initProgressDialog();
        mContactData = new ContactDetailData();
        mLoadContactDetailPresenter = new LoadContactDetailPresenter(this, this, getIntent().getData());
        ContactSaveService.registerListener(this);
    }

    private void initProgressDialog() {
        mProgressDialog = new ProgressDialog(this);
        mProgressDialog.setMessage(getResources().getString(R.string.update_contact_data_msg));
        mProgressDialog.setCancelable(false);
    }

    private void initView() {
        Toolbar toolbar = (Toolbar) this.findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        ImageView name_edit_img;
        ImageView number_edit_img;
        ImageView email_edit_img;
        ImageView address_edit_img;
        ImageView organization_edit_img;
        ImageView note_edit_img;
        ImageButton send_message_button;
        ImageButton send_email_button;
        ImageButton send_location_button;
        ImageButton send_organization_button;
//        Button cancel_button;
//        Button ok_button;
        collapsingToolbar =
                (CollapsingToolbarLayout) findViewById(R.id.collapsing_toolbar);
//        collapsingToolbar.setTitle("name");
        contact_photo_view = (ImageView) findViewById(R.id.backdrop);
        contact_photo_view.setOnClickListener(this);
        name_edit_img = (ImageView) findViewById(R.id.detail_name_edit_bn);
        name_edit_img.setOnClickListener(this);
        number_edit_img = (ImageView) findViewById(R.id.detail_number_edit_bn);
        number_edit_img.setOnClickListener(this);
        email_edit_img = (ImageView) findViewById(R.id.detail_email_edit_bn);
        email_edit_img.setOnClickListener(this);
        address_edit_img = (ImageView) findViewById(R.id.detail_address_edit_bn);
        address_edit_img.setOnClickListener(this);
        organization_edit_img = (ImageView) findViewById(R.id.detail_organization_edit_bn);
        organization_edit_img.setOnClickListener(this);
        note_edit_img = (ImageView) findViewById(R.id.detail_note_edit_bn);
        note_edit_img.setOnClickListener(this);

        name_textView = (TextView) findViewById(R.id.detail_name_edit);
        number_textView = (TextView) findViewById(R.id.detail_number_edit);
        email_textView = (TextView) findViewById(R.id.detail_email_edit);
        address_textView = (TextView) findViewById(R.id.detail_address_edit);
        organization_textView = (TextView) findViewById(R.id.detail_organization_edit);
        note_textView = (TextView) findViewById(R.id.detail_note_edit);
        send_message_button = (ImageButton) findViewById(R.id.detail_message_button);
        send_message_button.setOnClickListener(this);
        send_email_button = (ImageButton) findViewById(R.id.detail_send_email_button);
        send_email_button.setOnClickListener(this);
        send_location_button = (ImageButton) findViewById(R.id.detail_location_button);
        send_location_button.setOnClickListener(this);
        send_organization_button = (ImageButton) findViewById(R.id.detail_organization_button);
        send_organization_button.setOnClickListener(this);
//        cancel_button = (Button) findViewById(R.id.detail_cancel);
//        cancel_button.setOnClickListener(this);
//        ok_button = (Button) findViewById(R.id.detail_ok);
//        ok_button.setOnClickListener(this);
    }

    @Override
    protected void onStart() {
        super.onStart();
        mLoadContactDetailPresenter.onStart();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mLoadContactDetailPresenter.onDestroy();
        ContactSaveService.unregisterListener(this);
    }

    public void call_onClick(View view) {
        if (mContactData.getContact_number() != null) {
            Intent intent = CallUtil.getCallIntent(mContactData.getContact_number());
            startActivity(intent);
        }
    }

    @Override
    public void requestContactData(ContactDetailData contactData) {
        mContactData = contactData;
        collapsingToolbar.setTitle(mContactData.getContact_name());
        name_textView.setText(mContactData.getContact_name());
        number_textView.setText(mContactData.getContact_number());
        email_textView.setText(mContactData.getContact_email());
        address_textView.setText(mContactData.getAddress());
        note_textView.setText(mContactData.getNote());
        organization_textView.setText(mContactData.getOrganization());
        if (null != mContactData.getContact_photo_bitmap()) {
            contact_photo_view.setImageBitmap(mContactData.getContact_photo_bitmap());
        }
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.detail_message_button: {
                String number = number_textView.getText().toString();
                if (!TextUtils.isEmpty(number)) {
                    Intent intent = new Intent(Intent.ACTION_SENDTO, Uri.fromParts("smsto",
                            number, null));
                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    startActivity(intent);
                }
            }
            break;
            case R.id.detail_send_email_button: {
                String email = email_textView.getText().toString();
                if (!TextUtils.isEmpty(email)) {
                    Uri mailUri = Uri.fromParts("mailto", email, null);
                    Intent intent = new Intent(Intent.ACTION_SENDTO, mailUri);
                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    startActivity(intent);
                }
            }
            break;
            case R.id.detail_location_button: {
                String address = address_textView.getText().toString();
                if (!TextUtils.isEmpty(address)) {
                    Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("geo:0,0?q=" + Uri.encode(address)));
                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    startActivity(intent);
                }
            }
            break;
            case R.id.detail_organization_button: {
                String organization = organization_textView.getText().toString();
                if (!TextUtils.isEmpty(organization)) {
                    Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("geo:0,0?q=" + Uri.encode(organization)));
                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    startActivity(intent);
                }
            }
            break;
            case R.id.backdrop: {
                showPopupWindow();
            }
            break;
            case R.id.detail_cancel:
                onBackPressed();
                break;
            case R.id.detail_ok: {
                updateContact();
                onBackPressed();
            }
            break;
            case R.id.detail_name_edit_bn: {
                InputDialogFragment inputDialogFragment = InputDialogFragment.newInstance(v.getId(),
                        getResources().getString(R.string.detail_name_title), name_textView.getText().toString());
                inputDialogFragment.setListener(this);
                inputDialogFragment.show(getFragmentManager(), "");
            }
            break;
            case R.id.detail_number_edit_bn: {
                InputDialogFragment inputDialogFragment = InputDialogFragment.newInstance(v.getId(),
                        getResources().getString(R.string.detail_number_title), number_textView.getText().toString());
                inputDialogFragment.setListener(this);
                inputDialogFragment.show(getFragmentManager(), "");
            }
            break;
            case R.id.detail_email_edit_bn: {
                InputDialogFragment inputDialogFragment = InputDialogFragment.newInstance(v.getId(),
                        getResources().getString(R.string.detail_email_title), email_textView.getText().toString());
                inputDialogFragment.setListener(this);
                inputDialogFragment.show(getFragmentManager(), "");
            }
            break;
            case R.id.detail_address_edit_bn: {
                InputDialogFragment inputDialogFragment = InputDialogFragment.newInstance(v.getId(),
                        getResources().getString(R.string.detail_address_title), address_textView.getText().toString());
                inputDialogFragment.setListener(this);
                inputDialogFragment.show(getFragmentManager(), "");
            }
            break;
            case R.id.detail_organization_edit_bn: {
                InputDialogFragment inputDialogFragment = InputDialogFragment.newInstance(v.getId(),
                        getResources().getString(R.string.detail_organization_title), organization_textView.getText().toString());
                inputDialogFragment.setListener(this);
                inputDialogFragment.show(getFragmentManager(), "");
            }
            break;
            case R.id.detail_note_edit_bn: {
                InputDialogFragment inputDialogFragment = InputDialogFragment.newInstance(v.getId(),
                        getResources().getString(R.string.detail_note_title), note_textView.getText().toString());
                inputDialogFragment.setListener(this);
                inputDialogFragment.show(getFragmentManager(), "");
            }
            break;
        }
    }

    private void showPopupWindow() {
        mTempPhotoUri = ContactPhotoUtils.generateTempImageUri(this);
        mCroppedPhotoUri = ContactPhotoUtils.generateTempCroppedImageUri(this);
        mPhotoPickSize = getPhotoPickSize();

        final ArrayList<String> choices = new ArrayList<>();
        choices.add(getResources().getString(R.string.select_photo_menu));
        choices.add(getResources().getString(R.string.tack_photo_menu));
        final ListAdapter adapter = new ArrayAdapter<>(this,
                R.layout.select_dialog_item, choices);
        final ListPopupWindow listPopupWindow = new ListPopupWindow(this);
        final AdapterView.OnItemClickListener clickListener = new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                switch (position) {
                    case 0: {
                        try {
                            // Launch picker to choose photo for selected contact
                            startPickFromGalleryActivity(mTempPhotoUri);
                        } catch (ActivityNotFoundException e) {
                            e.printStackTrace();
                        }
                    }
                    break;
                    case 1: {
                        try {
                            // Launch camera to take photo for selected contact
                            startTakePhotoActivity(mTempPhotoUri);
                        } catch (ActivityNotFoundException e) {
                            e.printStackTrace();
                        }
                    }

                    break;
                }
                if (listPopupWindow.isShowing()) {
                    listPopupWindow.dismiss();
                }
            }
        };

        listPopupWindow.setAnchorView(collapsingToolbar);
        listPopupWindow.setAdapter(adapter);
        listPopupWindow.setOnItemClickListener(clickListener);
        listPopupWindow.setModal(true);
        listPopupWindow.setInputMethodMode(ListPopupWindow.INPUT_METHOD_NOT_NEEDED);
        listPopupWindow.setWidth(400);
        listPopupWindow.show();
    }

    private void updateContactPhoto(byte[] compressed){
        if (!mProgressDialog.isShowing()) {
            mProgressDialog.show();
        }
        try {
            ContactDetailData mContactDetailData = new ContactDetailData();//(ContactDetailData) mContactData.clone();
            mContactDetailData.setContact_id(mContactData.getContact_id());
            mContactDetailData.setPhoto(compressed);
            Intent intent = ContactSaveService.createUpdateContactPhotoIntent(this, mContactDetailData, DetailActivity.class, "DetailActivity");
            startService(intent);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void updateContact() {
        if (!mProgressDialog.isShowing()) {
            mProgressDialog.show();
        }
        try {
            ContactDetailData mContactDetailData = new ContactDetailData();//(ContactDetailData) mContactData.clone();
            mContactDetailData.setContact_id(mContactData.getContact_id());
            String name = name_textView.getText().toString();
            String number = number_textView.getText().toString();
            String email = email_textView.getText().toString();
            String address = address_textView.getText().toString();
            String organization = organization_textView.getText().toString();
            String note = note_textView.getText().toString();
            if (!TextUtils.isEmpty(name) && !name.equals(mContactData.getContact_name())) {
                mContactDetailData.setContact_name(name);
            }
            if (!TextUtils.isEmpty(number) && !number.equals(mContactData.getContact_number())){
                mContactDetailData.setContact_number(number);
            }
            if (!TextUtils.isEmpty(email) && !email.equals(mContactData.getContact_email())) {
                mContactDetailData.setContact_email(email);
            }
            if (!TextUtils.isEmpty(address)&& !address.equals(mContactData.getAddress())) {
                mContactDetailData.setAddress(address);
            }
            if (!TextUtils.isEmpty(organization) && !organization.equals(mContactData.getOrganization())){
                mContactDetailData.setOrganization(organization);
            }
            if (!TextUtils.isEmpty(note)&& !note.equals(mContactData.getNote())) {
                mContactDetailData.setNote(note);
            }
            Intent intent = ContactSaveService.createUpdateContactIntent(this, mContactDetailData, DetailActivity.class, "DetailActivity");
            startService(intent);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onFragmentInteraction(String text, int id) {
        switch (id) {
            case R.id.detail_name_edit_bn: {
                if (!TextUtils.isEmpty(text)) {
                    name_textView.setText(text);
                    collapsingToolbar.setTitle(text);
                    collapsingToolbar.invalidate();
                }
            }
            break;
            case R.id.detail_number_edit_bn: {
                if (!TextUtils.isEmpty(text)) {
                    number_textView.setText(text);
                }
            }
            break;
            case R.id.detail_email_edit_bn: {
                if (!TextUtils.isEmpty(text)) {
                    email_textView.setText(text);
                }
            }
            break;
            case R.id.detail_address_edit_bn: {
                if (!TextUtils.isEmpty(text)) {
                    address_textView.setText(text);
                }
            }
            break;
            case R.id.detail_organization_edit_bn: {
                if (!TextUtils.isEmpty(text)) {
                    organization_textView.setText(text);
                }
            }
            break;
            case R.id.detail_note_edit_bn: {
                if (!TextUtils.isEmpty(text)) {
                    note_textView.setText(text);
                }
            }
            break;
        }
        updateContact();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode == Activity.RESULT_OK) {
            switch (requestCode) {
                // Cropped photo was returned
                case REQUEST_CROP_PHOTO: {
                    final Uri uri;
                    if (data != null && data.getData() != null) {
                        uri = data.getData();
                    } else {
                        uri = mCroppedPhotoUri;
                    }

                    try {
                        // delete the original temporary photo if it exists
                        getContentResolver().delete(mTempPhotoUri, null, null);
                        Bitmap photo = ContactPhotoUtils.getBitmapFromUri(this, uri);
//                        contact_photo_view.setImageBitmap(photo);
//                        final int size = ContactsUtils.getThumbnailSize(this);
//                        final Bitmap scaled = Bitmap.createScaledBitmap(photo, size, size, false);
                        final byte[] compressed = ContactPhotoUtils.compressBitmap(photo);
                        if (compressed != null && !compressed.equals(mContactData.getPhoto())) {
                            updateContactPhoto(compressed);
                        }
                        return;
                    } catch (FileNotFoundException e) {
                        return;
                    }
                }

                // Photo was successfully taken or selected from gallery, now crop it.
                case REQUEST_CODE_PHOTO_PICKED_WITH_DATA:
                case REQUEST_CODE_CAMERA_WITH_DATA:
                    final Uri uri;
                    boolean isWritable = false;
                    if (data != null && data.getData() != null) {
                        uri = data.getData();
                    } else {
                        uri = mCurrentPhotoUri;
                        isWritable = true;
                    }
                    final Uri toCrop;
                    if (isWritable) {
                        // Since this uri belongs to our file provider, we know that it is writable
                        // by us. This means that we don't have to save it into another temporary
                        // location just to be able to crop it.
                        toCrop = uri;
                    } else {
                        toCrop = mTempPhotoUri;
                        try {
                            ContactPhotoUtils.savePhotoFromUriToUri(this, uri,
                                    toCrop, false);
                        } catch (SecurityException e) {
//                            Log.d(TAG, "Did not have read-access to uri : " + uri);
                            return;
                        }
                    }

                    doCropPhoto(toCrop, mCroppedPhotoUri);
            }
        }
    }

    @Override
    public boolean onLongClick(View v) {
        return false;
    }

    @Override
    public void onServiceCompleted(Intent callbackIntent) {
        if (mProgressDialog.isShowing()) {
            mProgressDialog.dismiss();
        }
    }

    /**
     * Sends a newly acquired photo to Gallery for cropping
     */
    private void doCropPhoto(Uri inputUri, Uri outputUri) {
        try {
            // Launch gallery to crop the photo
            final Intent intent = getCropImageIntent(inputUri, outputUri);
//            startPhotoActivity(intent, REQUEST_CROP_PHOTO, inputUri);
            mCurrentPhotoUri = inputUri;
            startActivityForResult(intent, REQUEST_CROP_PHOTO);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void startTakePhotoActivity(Uri photoUri) {
        final Intent intent = getTakePhotoIntent(photoUri);
//        startPhotoActivity(intent, REQUEST_CODE_CAMERA_WITH_DATA, photoUri);
        mCurrentPhotoUri = photoUri;
        startActivityForResult(intent, REQUEST_CODE_CAMERA_WITH_DATA);
    }

    private void startPickFromGalleryActivity(Uri photoUri) {
        final Intent intent = getPhotoPickIntent(photoUri);
//        startPhotoActivity(intent, REQUEST_CODE_PHOTO_PICKED_WITH_DATA, photoUri);
        mCurrentPhotoUri = photoUri;
        startActivityForResult(intent, REQUEST_CODE_PHOTO_PICKED_WITH_DATA);
    }

    private int getPhotoPickSize() {
        if (mPhotoDim != 0) {
            return mPhotoDim;
        }

        // Note that this URI is safe to call on the UI thread.
        Cursor c = getContentResolver().query(ContactsContract.DisplayPhoto.CONTENT_MAX_DIMENSIONS_URI,
                new String[]{ContactsContract.DisplayPhoto.DISPLAY_MAX_DIM}, null, null, null);
        if (c != null) {
            try {
                if (c.moveToFirst()) {
                    mPhotoDim = c.getInt(0);
                }
            } finally {
                c.close();
            }
        }
        return mPhotoDim != 0 ? mPhotoDim : mDefaultPhotoDim;
    }

    /**
     * Constructs an intent for capturing a photo and storing it in a temporary output uri.
     */
    private Intent getTakePhotoIntent(Uri outputUri) {
        final Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE, null);
        ContactPhotoUtils.addPhotoPickerExtras(intent, outputUri);
        return intent;
    }

    /**
     * Constructs an intent for picking a photo from Gallery, and returning the bitmap.
     */
    private Intent getPhotoPickIntent(Uri outputUri) {
        final Intent intent = new Intent(Intent.ACTION_GET_CONTENT, null);
        intent.setType("image/*");
        ContactPhotoUtils.addPhotoPickerExtras(intent, outputUri);
        return intent;
    }

    /**
     * Constructs an intent for image cropping.
     */
    private Intent getCropImageIntent(Uri inputUri, Uri outputUri) {
        Intent intent = new Intent("com.android.camera.action.CROP");
        intent.setDataAndType(inputUri, "image/*");
        ContactPhotoUtils.addPhotoPickerExtras(intent, outputUri);
        ContactPhotoUtils.addCropExtras(intent, mPhotoPickSize);
        return intent;
    }
}
